package me.sdevil507.biz.common.sms.captcha.controller;

import com.google.code.kaptcha.Producer;
import lombok.extern.slf4j.Slf4j;
import me.sdevil507.biz.common.sms.captcha.dto.CheckCaptchaParamsDTO;
import me.sdevil507.biz.common.sms.captcha.dto.SendCaptchaParamsDTO;
import me.sdevil507.biz.common.sms.captcha.enums.CaptchaType;
import me.sdevil507.biz.common.sms.captcha.service.CaptchaService;
import me.sdevil507.org.service.OrgUserService;
import me.sdevil507.supports.result.ApiResultDTO;
import me.sdevil507.supports.result.ApiResultGenerator;
import me.sdevil507.supports.status.ApiStatusCode;
import me.sdevil507.supports.status.ComConstant;
import org.apache.commons.lang3.EnumUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.concurrent.TimeUnit;

/**
 * 短信操作
 *
 * @author sdevil507
 */
@RestController
@RequestMapping("/api/common/captcha")
@Slf4j
public class CaptchaController {

    @Autowired
    private CaptchaService captchaService;
    @Autowired
    private OrgUserService orgUserService;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private Producer producer;

    /**
     * 发送验证码
     *
     * @param dto 发送验证码入参
     * @return 执行反馈
     */
    @PostMapping("/send")
    public ApiResultDTO send(@RequestBody @Valid SendCaptchaParamsDTO dto) {
        ApiResultDTO apiResultDTO;

        // 如果传递验证码类型不支持
        if (!EnumUtils.isValidEnum(CaptchaType.class, dto.getType().toUpperCase())) {
            return ApiResultGenerator.create(ApiStatusCode.CAPTCHA_TYPE_NOT_SUPPORT.getCode(), ApiStatusCode.CAPTCHA_TYPE_NOT_SUPPORT.getDescription());
        }

        // 如果非本系统用户,直接提示返回,不执行验证码发送
        if (!dto.getType().toUpperCase().equals(CaptchaType.REGISTER.name()) && !dto.getType().toUpperCase().equals(CaptchaType.BIND.name())) {
            boolean isHaveUser = true;
            //服务端
            if(ComConstant.LogSource.SERVICES.equals(dto.getTerminal())){
                if(!orgUserService.existsByPhoneNumber(dto.getPhoneNumber())){
                    isHaveUser = false;
                }
            }
            //专家端
            if(ComConstant.LogSource.EXPERT.equals(dto.getTerminal())){
                if(!orgUserService.existsByPhoneNumber(dto.getPhoneNumber())){
                    isHaveUser = false;
                }
            }
            if(!isHaveUser){
                return ApiResultGenerator.create(ApiStatusCode.CAPTCHA_ACCOUNT_NOT_EXISTED.getCode(), ApiStatusCode.CAPTCHA_ACCOUNT_NOT_EXISTED.getDescription());
            }
        }

        // 执行发送
        try {
            if (captchaService.send(CaptchaType.valueOf(dto.getType().toUpperCase()), dto.getPhoneNumber())) {
                apiResultDTO = ApiResultGenerator.create(ApiStatusCode.SUCCESS.getCode(), ApiStatusCode.SUCCESS.getDescription());
            } else {
                apiResultDTO = ApiResultGenerator.create(ApiStatusCode.CAPTCHA_SEND_ERROR.getCode(), ApiStatusCode.CAPTCHA_SEND_ERROR.getDescription());
            }
        } catch (Exception e) {
            log.error("发送验证码失败:", e);
            apiResultDTO = ApiResultGenerator.create(ApiStatusCode.ERROR.getCode(), ApiStatusCode.ERROR.getDescription());
        }
        return apiResultDTO;
    }

    /**
     * 校验验证码
     *
     * @param dto 校验验证码入参
     * @return 执行反馈
     */
    @PostMapping("/check")
    public ApiResultDTO check(@RequestBody @Valid CheckCaptchaParamsDTO dto) {
        ApiResultDTO apiResultDTO;
        // 如果传递验证码类型不支持
        if (!EnumUtils.isValidEnum(CaptchaType.class, dto.getType().toUpperCase())) {
            return ApiResultGenerator.create(ApiStatusCode.CAPTCHA_TYPE_NOT_SUPPORT.getCode(), ApiStatusCode.CAPTCHA_TYPE_NOT_SUPPORT.getDescription());
        }
        // 执行校验
        boolean state = captchaService.check(CaptchaType.valueOf(dto.getType().toUpperCase()), dto.getPhoneNumber(), dto.getCode());
        if (state) {
            apiResultDTO = ApiResultGenerator.create(ApiStatusCode.SUCCESS.getCode(), ApiStatusCode.SUCCESS.getDescription());
        } else {
            apiResultDTO = ApiResultGenerator.create(ApiStatusCode.CAPTCHA_INVALID.getCode(), ApiStatusCode.CAPTCHA_INVALID.getDescription());
        }
        return apiResultDTO;
    }

    @RequestMapping("/download")
    public void download(HttpServletResponse response) throws IOException {
        //绝对路径
        String inPath = "D:/222.zip";
//        String outPath = "D:/333.zip";

        File inFile = new File(inPath);
//        File outFile = new File(outPath);
        if (!inFile.exists()) {
            // TODO 文件不存在
        }
        BufferedInputStream in = new BufferedInputStream(new FileInputStream(inFile));
        OutputStream fileOutputStream = new BufferedOutputStream(response.getOutputStream());

        int buf_size = 10;
        byte[] buffer = new byte[buf_size];
        int len = 0;
        while (-1 != (len = in.read(buffer, 0, buf_size))) {
            fileOutputStream.write(buffer, 0, len);//一次仅传输1K，不会溢出
        }
        fileOutputStream.flush();

        fileOutputStream.close();
        System.out.println("测试完成");

    }

    @RequestMapping("/getImgCaptcha")
    public void getCaptcha(HttpServletRequest request, HttpServletResponse response){
        String captchaText = producer.createText();
        String key = captchaService.getImgCaptchaKey(request);
        // 十分钟过期
        stringRedisTemplate.opsForValue().set(key,captchaText,5, TimeUnit.MINUTES);
        BufferedImage image = producer.createImage(captchaText);
        ServletOutputStream outputStream=null;
        try {
            outputStream= response.getOutputStream();
            ImageIO.write(image,"jpg",outputStream);
            outputStream.flush();
            outputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @GetMapping("/checkImgCaptcha")
    public String check(HttpServletRequest request, HttpServletResponse response, @RequestParam String value){
        String key = captchaService.getImgCaptchaKey(request);
        String v = stringRedisTemplate.opsForValue().get(key);
        if (v.equals(value)){
            return "验证成功";
        }else {
            return "校验失败";
        }
    }

}
